package dev.ece.util.tools;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import dev.ece.util.lib.IntRectangle;

/**
 * 九宫格合并图片
 * @author 潜行的虚影
 *
 */
public class NineMerge {

	public static final int SIZE = 3;
	
	private BufferedImage image;
	
	private IntRectangle centerRectangle;
	
	private NineMerge() {}

	public static NineMerge createNineMerge(String filename, Screen[][] screens) throws IOException {
		return createNineMerge(new File(filename), screens);
	}
	
	public static NineMerge createNineMerge(File file, Screen[][] screens) throws IOException {
		BufferedImage image = ImageIO.read(file);
		return createNineMerge(image, screens);
	}
	
	public static NineMerge createNineMerge(InputStream input, Screen[][] screens) throws IOException {
		BufferedImage image = ImageIO.read(input);
		return createNineMerge(image, screens);
	}
	
	/**
	 * 
	 * @param image
	 * @param screens [3][3]
	 * @return
	 */
	public static NineMerge createNineMerge(BufferedImage image, Screen[][] screens) {
		BufferedImage[][] images = new BufferedImage[3][3];
		Screen screen = null;
		for(int row = 0; row<SIZE; row ++) {
			for(int col=0; col<SIZE; col ++) {
				screen = screens[row][col];
				images[row][col] = image.getSubimage(
						screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight());
			}
		}
		return createNineMerge(images);
	}
	
	public static NineMerge createNineMerge(String filename, Screen[] screens) throws IOException {
		return createNineMerge(new File(filename), screens);
	}
	
	public static NineMerge createNineMerge(File file, Screen[] screens) throws IOException {
		BufferedImage image = ImageIO.read(file);
		return createNineMerge(image, screens);
	}
	
	public static NineMerge createNineMerge(InputStream input, Screen[] screens) throws IOException {
		BufferedImage image = ImageIO.read(input);
		return createNineMerge(image, screens);
	}
	
	/**
	 * 合并横向3个图片，例如按钮
	 * @param image
	 * @param screens [3]
	 * @return
	 */
	public static NineMerge createNineMerge(BufferedImage image, Screen[] screens) {
		BufferedImage[] images = new BufferedImage[3];
		Screen screen = null;
		for(int col=0; col<SIZE; col ++) {
			screen = screens[col];
			images[col] = image.getSubimage(
					screen.getX(), screen.getY(), screen.getWidth(), screen.getHeight());
		}
		return createNineMerge(images);
	}
	
	/**
	 * 合并横向3个图片，例如按钮
	 * @param images [3]
	 * @return
	 */
	public static NineMerge createNineMerge(BufferedImage[] images) {
		IntRectangle center = new IntRectangle();
		center.top = 2;
		center.bottom = 2;
		center.left = images[0].getWidth();
		center.right = images[2].getWidth();
		int width = center.left + images[1].getWidth() + center.right;
		int height = Math.max(images[0].getHeight(), Math.max(images[1].getHeight(), images[2].getHeight()));
		int cwidth = images[1].getWidth();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		Graphics g = image.getGraphics();
		BufferedImage img = null;
		//top
		img = images[0];
		g.drawImage(img, center.left - img.getWidth(), (height - img.getHeight()) / 2, null);
		img = images[1];
		g.drawImage(img, center.left, (height - img.getHeight()) / 2, null);
		img = images[2];
		g.drawImage(img, center.left + cwidth, (height - img.getHeight()) / 2, null);
		g.dispose();
		NineMerge result = new NineMerge();
		result.image = image;
		result.centerRectangle = center;
		return result;
	}
	/**
	 * 横向合并图片
	 * @param images 
	 * @return
	 */
	public static BufferedImage createMergeImages(BufferedImage[] images, int distance) {
		int width = 0;
		int height = 0;
		BufferedImage image = null;
		for(int i=0; i<images.length; i++) {
			image = images[i];
			width += image.getWidth();
			height = Math.max(height, image.getHeight());
			if(i + 1 < images.length) {
				width += distance;
			}
		}
		BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		Graphics g = result.getGraphics();
		int x = 0;
		for(BufferedImage img: images) {
			g.drawImage(img, x, 0, null);
			x += img.getWidth() + distance;
		}
		g.dispose();
		return result;
	}

	/**
	 * 合并九宫格
	 * @param images [3][3]
	 * @return
	 */
	public static NineMerge createNineMerge(BufferedImage[][] images) {
		IntRectangle center = new IntRectangle();
		for(int row = 0; row<SIZE; row ++) {
			center.left = Math.max(center.left, images[row][0].getWidth());
			center.right = Math.max(center.right, images[row][2].getWidth());
		}
		for(int col = 0; col<SIZE; col ++) {
			center.top = Math.max(center.top, images[0][col].getHeight());
			center.bottom = Math.max(center.bottom, images[2][col].getHeight());
		}
		int cwidth = images[1][1].getWidth();
		int cheight = images[1][1].getHeight();
		int width = center.left + cwidth + center.right;
		int height = center.top + cheight + center.bottom;
		
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		Graphics g = image.getGraphics();
		BufferedImage img = null;
		//top
		img = images[0][0];
		g.drawImage(img, center.left - img.getWidth(), center.top - img.getHeight(), null);
		img = images[0][1];
		g.drawImage(img, center.left, center.top - img.getHeight(), null);
		img = images[0][2];
		g.drawImage(img, center.left + cwidth, center.top - img.getHeight(), null);
		//middle
		img = images[1][0];
		g.drawImage(img, center.left - img.getWidth(), center.top, null);
		img = images[1][1];
		g.drawImage(img, center.left, center.top, null);
		img = images[1][2];
		g.drawImage(img, center.left + cwidth, center.top, null);
		//bottom
		img = images[2][0];
		g.drawImage(img, center.left - img.getWidth(), center.top + cheight, null);
		img = images[2][1];
		g.drawImage(img, center.left, center.top + cheight, null);
		img = images[2][2];
		g.drawImage(img, center.left + cwidth, center.top + cheight, null);
		g.dispose();
		NineMerge result = new NineMerge();
		result.image = image;
		result.centerRectangle = center;
		return result;
	}
	
	public BufferedImage getImage() {
		return image;
	}

	public IntRectangle getCenterRectangle() {
		return centerRectangle;
	}
	
}
